#include <iostream>
#include <ctime>

using namespace std;

/*给定K个整数组成的序列{ N​1​​, N​2​​, ..., N​K​​ }，“连续子列”被定义为{ N​i​​, N​i+1​​, ..., N​j​​ }，其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 }，其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序，计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下：

    数据1：与样例等价，测试基本正确性；
    数据2：102个随机整数；
    数据3：103个随机整数；
    数据4：104个随机整数；
    数据5：105个随机整数；

输入格式:

输入第1行给出正整数K (≤100000)；第2行给出K个整数，其间以空格分隔。
输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数，则输出0。
输入样例:

6
-2 11 -4 13 -5 -2

输出样例:

20*/

int MaxSubseqSum1( int A[], int N )
{
    //使用三重循环，定义循环变量
    int i,j,k;
    //定义即时和与最大和
    int ThisSum, MaxSum = 0;
    for( i = 0; i < N; i++ )
    {
        for( j = i; j < N; j++ )//i是子列左端位置
        {
            ThisSum = 0;
            for( k = i; k <= j; k++ )//j是子列右端位置
                ThisSum += A[ k ];
            if( ThisSum > MaxSum )
                MaxSum = ThisSum; //更新最大和
        }//j循环结束
    }//i循环结束
    return MaxSum;
}

int MaxSubseqSum2( int A[], int N )
{
    //使用三重循环，定义循环变量
    int i,j;
    //定义即时和与最大和
    int ThisSum, MaxSum = 0;
    for( i = 0; i < N; i++ )//i是子列左端位置
    {
        ThisSum = 0;
        for( j = i; j < N; j++ )//j是子列右端位置
        {
            ThisSum += A[ j ]; // 只对相同的i，不同的j，只要在j-1次循环的基础上累加一项即可
            if( ThisSum > MaxSum )
                MaxSum = ThisSum; //更新最大和
        }//j循环结束
    }//i循环结束
    return MaxSum;
}

int MaxSubseqSum3( int A[], int N )
{
    //只使用一个循环，定义循环变量
    int i;
    int ThisSum = 0, MaxSum = 0;
    for( i = 0; i < N; i++ )
    {
        ThisSum += A[ i ];//向右累加
        if( ThisSum > MaxSum )
        {
            MaxSum = ThisSum;//发现更大则更新当前结果
        }
        if( ThisSum < 0 )
        {
            ThisSum = 0;//如果当前子列为负，则不可能使后面的部分和增大，抛弃之
        }
    }
    return MaxSum;
}

int MaxSubseqSum4()

double Getduration( int A[], int N, int (*pf)(int*, int) )
{
    clock_t start, stop;
    double TIMES = 1e7; //重复次数
    int i; //循环变量

    start = clock();
    for( i = 0 ; i < TIMES ; i ++ )
    {
        //复习一下函数指针
        pf( A, N );
    }
    stop = clock();

    double duration = (( double )( stop - start )); //总耗时

    return duration;
}

int main()
{
    cout << "请输入数组规模：" << endl;
    int N;
    cin >> N;
    int* pArr = new int [ N ];
    int i;
    cout << "请初始化数组：" << endl;
    for( i = 0; i < N; i++ )
    {
        cin >> pArr[ i ];
    }

    cout << MaxSubseqSum2( pArr, N ) << endl;

    //得到结果
    double result = MaxSubseqSum3( pArr, N );
    cout << "结果为：" << result << endl;
    //算法一耗时
    double duration1 = Getduration(pArr, N, MaxSubseqSum1);
    //算法二耗时
    double duration2 = Getduration(pArr, N, MaxSubseqSum2);
    //算法三耗时
    double duration3 = Getduration(pArr, N, MaxSubseqSum3);

    cout << "注意：重复运行1e7次后" << endl;
    cout << "算法1总耗时: " << duration1 << endl;
    cout << "算法2总耗时: " << duration2 << endl;
    cout << "算法3总耗时: " << duration3 << endl;

    return 0;
}
